from google.appengine.ext import db

class Proyecto(db.Model):
    usuario = db.UserProperty(required=True, auto_current_user_add=True)
    nombre = db.StringProperty(required=True, multiline=False)
    descripcion = db.StringProperty(multiline=False)
    mostrar = db.BooleanProperty(required=True, default=True)
    fecha_mod = db.DateTimeProperty(auto_now=True)

    @classmethod
    def nuevo(cls, nombre, descripcion=None):
        if nombre:
            if not descripcion:
                descripcion = None
            p = Proyecto(nombre=nombre, descripcion=descripcion)
            p.put()

    @classmethod
    def modificar(cls, u, p_id, n_nombre, n_descripcion=None, n_mostrar=True):
        if n_nombre and p_id != -1:
            if not n_descripcion:
                n_descripcion = None
            p = cls.get_by_id(p_id)
            if p and p.usuario == u:
                p.nombre = n_nombre
                p.descripcion = n_descripcion
                p.mostrar = bool(n_mostrar)
                p.put()
                return True

    @classmethod
    def borrar(cls, u, p):
        '''
        Tenemos que verificar que la id de proyecto pertenezca al usuario
        activo.
        A continuacion borrar el proyecto.
        Consultar las tareas con el usuario activo y el proyecto que buscamos.
        Borrar su asignacion del proyecto.
        '''
        proyecto = cls.get_by_id(p)
        if proyecto and proyecto.usuario == u:
            Tarea.desenlazar(u, p)
            proyecto.delete()
            return True

    @classmethod
    def listar(cls, u):
        res = []
        p_list = cls.all().filter('usuario =', u).run()
        for p in p_list:
            p.id = p.key().id()
            res.append(p)
        return res
    
    @classmethod
    def existe(cls, u, p):
        proyecto = cls.get_by_id(p)
        if proyecto and proyecto.usuario == u:
            return True

class Tarea(db.Model):
    usuario = db.UserProperty(required=True, auto_current_user_add=True)
    nombre = db.StringProperty(required=True, multiline=False)
    descripcion = db.StringProperty(multiline=False)
    proyecto = db.IntegerProperty(required=True, default=-1)
    limite = db.DateProperty() 
    mail = db.BooleanProperty(required=True, default=False)
    alarma = db.TimeProperty()
    importancia = db.IntegerProperty(required=True, choices=[1, 2, 3])
    #1:baja, 2:media, 3:alta 
    estado = db.IntegerProperty(required=True, choices=[1, 2, 3, 4, 5])
    #1:No planificado, 2:Planificado, 3:Empezado, 4:Proximo a su fin, 5:Finalizado
    fecha_mod = db.DateTimeProperty(auto_now=True)
    
    @classmethod
    def nueva(cls, usuario, nombre, descripcion=None, proyecto=-1, limite=None, mail=False, alarma=None, importancia=2, estado=1):
        if nombre and (proyecto == -1 or Proyecto.existe(usuario, proyecto)):
            if alarma and not limite:
                alarma = None
            if not descripcion:
                descripcion = None
            t = Tarea(nombre=nombre, descripcion=descripcion, mail=bool(mail), limite=limite, importancia=importancia, estado=estado, alarma=alarma, proyecto=proyecto)
            t.put()
            return True
    
    @classmethod
    def listar(cls, u):
        t_list = cls.all().filter('usuario =', u).run()
        res = []
        for t in t_list:
            t.id = t.key().id()
            res.append(t)
        return res
    
    @classmethod
    def listar_ocultando(cls, u):
        t_list = cls.all().filter('usuario =', u).run()
        res = []
        for t in t_list:
            t.id = t.key().id()
            if t.proyecto == -1:
                res.append(t)
            else:
                p = Proyecto.get_by_id(t.proyecto)
                if p and p.mostrar:
                    res.append(t)
        return res
    
    @classmethod
    def modificar(cls, u, t_id, n, d, p, f, c, a, i, e):
        if n and (p == -1 or Proyecto.existe(u, p)):
            if a and not f:
                a = None
            if not d:
                d = None
            t = cls.get_by_id(t_id)
            if t and t.usuario == u:
                t.nombre = n
                t.descripcion = d
                t.proyecto = p
                t.limite = f
                t.mail = bool(c)
                t.alarma = a
                t.importancia = i
                t.estado = e
                t.put()
                return True
        
    @classmethod
    def borrar(cls, u, t):
        t = cls.get_by_id(t)
        if t and t.usuario == u:
            t.delete()
            return True
        
    
    @classmethod
    def desenlazar(cls, u, p):
        '''
        Este metodo busca todas las tareas de un usuario asignado a un
        numero de proyecto y las desenlaza.
        La busqueda por usuario la hacemos por motivos de seguridad.
        '''
        t_list = cls.all().filter('usuario =', u).filter('proyecto =', p).run()
        for t in t_list:
            t.proyecto = -1
            t.put()
    
    @classmethod
    def existe(cls, u, t):
        tarea = cls.get_by_id(t)
        if tarea and tarea.usuario == u:
            return True
            
class Opciones(db.Model):
    usuario = db.UserProperty(required=True, auto_current_user_add=True)
    orden = db.StringListProperty()
    proyectos_ocultos = db.ListProperty(item_type = int)
    po = db.ListProperty(item_type = int)
    
    @classmethod
    def buscar(cls, u):
        return cls.all().filter('usuario =', u).get()
    
    @classmethod
    def insertar(cls, u):
        o = Opciones(usuario=u, orden=[], proyectos_ocultos=[])
        o.put()
    